package com.neusoft.boss.common.interceptors;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.neusoft.boss.common.client.RedisClient;
import com.neusoft.boss.common.consanst.KeyConst;
import com.neusoft.boss.common.enums.AjaxCode;
import com.neusoft.boss.common.result.R;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;

/**
 * 验证jwt的拦截器
 * token拦截器继承mvc的拦截器
 * 重写preHandle方法
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {

    //从redis中取出token
    @Resource
    private RedisClient redisClient;

    //使用构造方法注入

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //处理预检请求：放行
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }


        //其他请求，从header中获取操作员和jwt
        String authorization = request.getHeader("Authorization");//取jwt
        String operatorId = request.getHeader("operatorId");//取操作员id
        if (StrUtil.isNotBlank(authorization) && StrUtil.isNotBlank(operatorId)&&authorization.startsWith("Bearer")) {
            String jwt = authorization.substring(7);
            //取出来jwt后再与redis中的jwt相比
            if (StrUtil.isNotBlank(jwt)) {
                String key = KeyConst.OPERATOR_LOGIN_JWT+operatorId;
                String redisKey = redisClient.getKey(key, jwt);
                if (key.equals(redisKey)) {
                    return true;
                }
            }
        }
        try {
            //jwt无效
            R fail = R.Fail(AjaxCode.LOGIN_TOKEN_INVALID);
            response.setContentType("application/json;charset = UTF-8");//设置输出类型
            PrintWriter out = response.getWriter();
            out.print(JSONUtil.toJsonStr(fail));
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("登陆无效");
        }
        return false;
    }
}
